package org.gap.jseed;

import static javassist.CtClass.booleanType;
import static javassist.CtClass.byteType;
import static javassist.CtClass.charType;
import static javassist.CtClass.doubleType;
import static javassist.CtClass.floatType;
import static javassist.CtClass.intType;
import static javassist.CtClass.voidType;
import javassist.CtClass;
import javassist.NotFoundException;

import static org.gap.jseed.JavaWriter.*;

public class PrimitiveJavaWriter {
	
	protected static String writePrimitiveSaveReturn(CtClass primitiveType, String body) throws NotFoundException {
		String result = line("return ($r)" + body);
		if (defaultValue(primitiveType).equalsIgnoreCase(body)) {
			result = line(result);
		} else 
		if (primitiveType.isPrimitive()) {
			String clazz = getPrimitiveType(primitiveType);
					String method = getPrimitiveMethod(primitiveType);
					result = line("Object result = " + body) +  
					"try {\n" +
					line("    return ($r)" + clazz + ".parse" + method + "(\"\" + result)") +
					"} catch(RuntimeException e) {\n" + 
					line("    return ($r)" + defaultValue(primitiveType)) + 
					"}";
		}
		return result;
	}

	private static String getPrimitiveType(CtClass primitiveType) {
		if (primitiveType.getName().equals("int"))
			return "Integer";
		else if (primitiveType.getName().equals("boolean")) 
			return "Boolean";
		else if (primitiveType.getName().equals("long"))
			return "Long";
		else if (primitiveType.getName().equals("char"))
			return "Byte";
		else if (primitiveType.getName().equals("double"))
			return "Double";
		else if (primitiveType.getName().equals("float"))
			return "Float";
		else if (primitiveType.getName().equals("byte"))
			return "Byte";
		return "";
	}
	
	/**
	 * Returns the Primitive object to be matched with the given primitive type.  the
	 * only excpetion is the {@code char} since
	 * @param primitiveType
	 * @return
	 */
	private static String getPrimitiveMethod(CtClass primitiveType) {
		if (primitiveType.getName().equals("int"))
			return "Int";
		else if (primitiveType.getName().equals("boolean")) 
			return "Boolean";
		else if (primitiveType.getName().equals("long"))
			return "Long";
		else if (primitiveType.getName().equals("char"))
			return "Byte";
		else if (primitiveType.getName().equals("double"))
			return "Double";
		else if (primitiveType.getName().equals("float"))
			return "Float";
		else if (primitiveType.getName().equals("byte"))
			return "Byte";
		return "";
	}

	/**
	 * Ensures the a proper default value is created.
	 * 
	 * @param returnType
	 * @return
	 * @throws NotFoundException 
	 */
	public static String defaultValue(CtClass returnType) throws NotFoundException {
		if (booleanType.equals(returnType)) return "false";
		if (byteType.equals(returnType))    return "0";
		if (charType.equals(returnType))    return "0";
		if (doubleType.equals(returnType))  return "0.0d";
		if (floatType.equals(returnType))   return "0.0f";
		if (intType.equals(returnType))		return "0";
		if (voidType.equals(returnType)) return "";
		return "null";
	}
}
